package com.example.vaultmysql.service;

import com.example.vaultmysql.entity.DatabaseConfig;
import com.example.vaultmysql.entity.VaultConfig;
import com.example.vaultmysql.repository.DatabaseConfigRepository;
import com.example.vaultmysql.repository.VaultConfigRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据初始化服务
 * 负责初始化系统基础数据
 * 
 * @author System
 * @version 1.0.0
 */
@Slf4j
@Service
public class DataInitializationService implements CommandLineRunner {

    @Autowired
    private DatabaseConfigRepository databaseConfigRepository;

    @Autowired
    private VaultConfigRepository vaultConfigRepository;

    @Override
    public void run(String... args) throws Exception {
        log.info("开始初始化系统数据...");
        
        initializeVaultConfig();
        initializeDatabaseConfigs();
        
        log.info("系统数据初始化完成");
    }

    /**
     * 初始化Vault配置
     */
    private void initializeVaultConfig() {
        if (vaultConfigRepository.count() == 0) {
            VaultConfig vaultConfig = new VaultConfig();
            vaultConfig.setVaultUrl("http://localhost:8200");
            vaultConfig.setAuthMethod("AppRole");
            vaultConfig.setNamespace("default");
            vaultConfig.setRoleId("your-role-id");
            vaultConfig.setEnabled(true);
            vaultConfig.setCreatedAt(LocalDateTime.now());
            
            vaultConfigRepository.save(vaultConfig);
            log.info("初始化Vault配置完成");
        } else {
            log.info("Vault配置已存在，跳过初始化");
        }
    }

    /**
     * 初始化数据库配置（50个数据库）
     */
    private void initializeDatabaseConfigs() {
        if (databaseConfigRepository.count() == 0) {
            List<DatabaseConfig> configs = new ArrayList<>();
            
            // 创建50个数据库配置
            for (int i = 1; i <= 50; i++) {
                DatabaseConfig config = new DatabaseConfig();
                config.setName(String.format("database_%02d", i));
                config.setHost(getHostForDatabase(i));
                config.setPort(getPortForDatabase(i));
                config.setSchemaName(String.format("schema_%02d", i));
                config.setVaultPath(String.format("/secret/database/db_%02d", i));
                config.setEnabled(true);
                config.setCreatedAt(LocalDateTime.now());
                config.setUpdatedAt(LocalDateTime.now());
                
                configs.add(config);
            }
            
            databaseConfigRepository.saveAll(configs);
            log.info("初始化50个数据库配置完成");
        } else {
            log.info("数据库配置已存在，跳过初始化");
        }
    }

    /**
     * 获取数据库主机地址
     * 模拟分布在不同服务器上的数据库
     */
    private String getHostForDatabase(int index) {
        // 模拟5个不同的数据库服务器
        int serverIndex = (index - 1) % 5 + 1;
        return String.format("mysql-server-%02d.example.com", serverIndex);
    }

    /**
     * 获取数据库端口
     * 模拟不同端口的数据库实例
     */
    private Integer getPortForDatabase(int index) {
        // 基础端口3306，每10个数据库使用不同端口
        int portOffset = (index - 1) / 10;
        return 3306 + portOffset;
    }

    /**
     * 手动初始化示例数据库凭证到Vault
     * 注意：这只是示例，实际环境中应该通过Vault CLI或API手动配置
     */
    public void initializeVaultCredentials() {
        log.info("=== Vault凭证初始化说明 ===");
        log.info("请手动在Vault中配置以下数据库凭证：");
        
        for (int i = 1; i <= 50; i++) {
            String vaultPath = String.format("/secret/database/db_%02d", i);
            String username = String.format("user_%02d", i);
            String password = String.format("password_%02d", i);
            
            log.info("vault kv put {} username={} password={}", vaultPath, username, password);
        }
        
        log.info("=== 或者使用以下API调用 ===");
        for (int i = 1; i <= 50; i++) {
            String vaultPath = String.format("secret/database/db_%02d", i);
            String username = String.format("user_%02d", i);
            String password = String.format("password_%02d", i);
            
            log.info("curl -X POST -H \"X-Vault-Token: $VAULT_TOKEN\" " +
                    "-d '{\"data\":{\"username\":\"{}\",\"password\":\"{}\"}}' " +
                    "http://localhost:8200/v1/{}", username, password, vaultPath);
        }
    }

    /**
     * 创建测试数据库配置
     */
    public List<DatabaseConfig> createTestDatabaseConfigs(int count) {
        List<DatabaseConfig> configs = new ArrayList<>();
        
        for (int i = 1; i <= count; i++) {
            DatabaseConfig config = new DatabaseConfig();
            config.setName(String.format("test_db_%02d", i));
            config.setHost("localhost");
            config.setPort(3306 + (i % 5)); // 使用不同端口
            config.setSchemaName(String.format("test_schema_%02d", i));
            config.setVaultPath(String.format("/secret/test/db_%02d", i));
            config.setEnabled(true);
            config.setCreatedAt(LocalDateTime.now());
            config.setUpdatedAt(LocalDateTime.now());
            
            configs.add(config);
        }
        
        return databaseConfigRepository.saveAll(configs);
    }

    /**
     * 清理所有测试数据
     */
    public void cleanupTestData() {
        log.info("清理测试数据...");
        
        // 删除测试数据库配置
        List<DatabaseConfig> testConfigs = databaseConfigRepository.findByNameContainingIgnoreCase("test_");
        if (!testConfigs.isEmpty()) {
            databaseConfigRepository.deleteAll(testConfigs);
            log.info("删除 {} 个测试数据库配置", testConfigs.size());
        }
        
        log.info("测试数据清理完成");
    }

    /**
     * 重置所有数据
     */
    public void resetAllData() {
        log.warn("重置所有数据...");
        
        databaseConfigRepository.deleteAll();
        vaultConfigRepository.deleteAll();
        
        // 重新初始化
        initializeVaultConfig();
        initializeDatabaseConfigs();
        
        log.warn("所有数据已重置并重新初始化");
    }

    /**
     * 获取系统初始化状态
     */
    public InitializationStatus getInitializationStatus() {
        long vaultConfigCount = vaultConfigRepository.count();
        long databaseConfigCount = databaseConfigRepository.count();
        long enabledDatabaseCount = databaseConfigRepository.countByEnabledTrue();
        
        boolean isInitialized = vaultConfigCount > 0 && databaseConfigCount >= 50;
        
        return new InitializationStatus(
            isInitialized,
            vaultConfigCount,
            databaseConfigCount,
            enabledDatabaseCount
        );
    }

    /**
     * 初始化状态信息
     */
    public static class InitializationStatus {
        private final boolean initialized;
        private final long vaultConfigCount;
        private final long databaseConfigCount;
        private final long enabledDatabaseCount;
        
        public InitializationStatus(boolean initialized, long vaultConfigCount, 
                                  long databaseConfigCount, long enabledDatabaseCount) {
            this.initialized = initialized;
            this.vaultConfigCount = vaultConfigCount;
            this.databaseConfigCount = databaseConfigCount;
            this.enabledDatabaseCount = enabledDatabaseCount;
        }
        
        public boolean isInitialized() { return initialized; }
        public long getVaultConfigCount() { return vaultConfigCount; }
        public long getDatabaseConfigCount() { return databaseConfigCount; }
        public long getEnabledDatabaseCount() { return enabledDatabaseCount; }
        
        @Override
        public String toString() {
            return String.format(
                "InitializationStatus{initialized=%s, vaultConfigs=%d, databaseConfigs=%d, enabledDatabases=%d}",
                initialized, vaultConfigCount, databaseConfigCount, enabledDatabaseCount
            );
        }
    }
}